//
// Log.cs
//
// Copyright (C) 2007 Fredrik Hedberg <fredrik@avafan.com>
// Copyright (C) 2008 Lukas Lipka <lukaslipka@gmail.com>
//

using System;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using System.Collections.Generic;

using Dashboard;

namespace Dashboard.Engine
{
	public class Log : IService
	{
		private object locker = new object ();

		public void Initialize ()
		{
		}

		public void Dispose ()
		{
		}

		public void Debug (string message_format, params object[] parameters)
		{
			Output (ConsoleColor.Blue, "DEBUG", message_format, parameters);
		}

		public void Debug (Exception e)
		{
			Output (ConsoleColor.Blue, "DEBUG", e.ToString ());
		}

		public void Info (string message_format, params object[] parameters)
		{
			Output (ConsoleColor.Green, "INFO", message_format, parameters);
		}

		public void Info (Exception e)
		{
			Output (ConsoleColor.Green, "INFO", e.ToString ());
		}

		public void Warn (string message_format, params object[] parameters)
		{
			Output (ConsoleColor.DarkYellow, "WARN", message_format, parameters);
		}

		public void Warn (Exception e)
		{
			Output (ConsoleColor.DarkYellow, "WARN", e.ToString ());
		}

		public void Error (string message_format, params object[] parameters)
		{
			Output (ConsoleColor.Red, "ERROR", message_format, parameters);
		}

		public void Error (Exception e)
		{
			Output (ConsoleColor.Red, "ERROR", e.ToString ());
		}

		private void Output (ConsoleColor c, string prefix, string format, params object[] args)
		{
			lock (locker) {
				OutputUnlocked (c, prefix, format, args);
			}
		}

		private void OutputUnlocked (ConsoleColor color, string prefix, string format, params object[] args)
		{
			// Write the sweet-colored debug prefix

			Console.ForegroundColor = color;
			Console.Write ("{0}:", prefix);
			Console.ResetColor ();

			// Print the stacktrace method type

			// FIXME: I'm not quite sure how expensive this
			// is, we should look into profiling it against
			// the previous revision

			StackFrame stack_frame = new StackFrame (3);
			MemberInfo member_info = stack_frame.GetMethod ();

			if (member_info.DeclaringType != null)
				Console.Write (" {0} -", member_info.DeclaringType);

			// Print the actual message

			string message = String.Format (format, args);
			Console.WriteLine (" {0} ", message);
		}
	}
}
